package com.example.myfirstprj;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.res.Resources.NotFoundException;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;

public abstract class Screen extends Fragment {
    public static boolean DISPOSE_RELOAD_SOUND = true;
    protected boolean canTouch = false;
    private Bundle mPersistentStates;
    public void setPersistentStates(Bundle states) {
        mPersistentStates = states;
    }
    public static Screen createInstance(String screenId, Bundle args) {
        Screen ret = null;
        try {
            Class<?> fragmentClass = Class.forName(screenId);
            ret = (Screen) fragmentClass.newInstance();
            ret.setArguments(args);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }


    public static Screen createInstance(Class<? extends Screen> screenClazz, Bundle args) {
        Screen ret = null;
        try {
            ret = (Screen) screenClazz.newInstance();
            ret.setArguments(args);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    public final static String getScreenId(Class<? extends Screen> scrClass) {
        return scrClass.getName();
    }

    public final String getScreenId() {
        return getScreenId(getClass());
    }

    private int mLayout;

    public final void setLayout(int layout) {
        mLayout = layout;
    }

    public View getContentView() {
        return mContentView;
    }


    private View mRootView, mContentView, mHeaderBarBg;
    private View mHeaderBar;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, final Bundle savedInstanceState) {
        mInflater = inflater;
        if (mRootView != null) {
            ((ViewGroup) mRootView.getParent()).removeView(mRootView);
            return mRootView;
        }

        final View root = inflater.inflate(R.layout.base_screen, container, false);
        mRootView = root;

        View v = null;
        if (mLayout > 0) {
            v = inflater.inflate(mLayout, container, false);
        } else {
            v = instantiateContentView(inflater, container, savedInstanceState);
        }

        if (v != null) {
            ViewGroup contentContainer = (ViewGroup) root.findViewById(R.id.container);
            contentContainer.addView(v);
        }
        return root;
    }

    protected View instantiateContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return null;
    }

    protected void onContentViewAboutToCreated(Bundle savedInstanceState) {

    }

    private boolean mHasActivityCreated = false;
    private Bundle mTempSavedInstanceStates;

    @Override
    public final void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        MainActivity act = getMainActivity();
        if (act != null) act.mCurrentScreenId = getScreenId();
        if (act instanceof MainActivity) {
            mHasActivityCreated = true;
            mTempSavedInstanceStates = savedInstanceState;

            if (mPersistentStates != null) {
                if (mTempSavedInstanceStates == null)
                    mTempSavedInstanceStates = mPersistentStates;
                else
                    mTempSavedInstanceStates.putAll(mPersistentStates);

                mPersistentStates = null;
            }

            onContentViewAboutToCreated(mTempSavedInstanceStates);

            if (mHasAnimationFinished) {
                postOnContentViewCreated();
            }
        }

    }


    private int mOverrideNextAnim = -1;

    void overrideNextAnimation(int anim) {
        mOverrideNextAnim = anim;
    }

    @Override
    public Animation onCreateAnimation(int transit, boolean enter, int theNextAnim) {
        final int nextAnim = mOverrideNextAnim >= 0 ? mOverrideNextAnim : theNextAnim;
        mHasAnimationFinished = false;
        if (enter) {
            if (nextAnim > 0) {
                Animation at = null;
                try {
                    at = AnimationUtils.loadAnimation(getActivity(), nextAnim);

                } catch (NotFoundException ne) {
                }

                if (at != null) {
                    at.setAnimationListener(new AnimationListener() {
                        @Override
                        public void onAnimationStart(Animation animation) {
                        }

                        @Override
                        public void onAnimationRepeat(Animation animation) {
                        }

                        @Override
                        public void onAnimationEnd(Animation animation) {
                            Log.i("Screen", "onAnimationEnd: " + getScreenId());
                            if (mHasActivityCreated) {
                                // We make a short delay here to make sure the animation is completely finished,
                                // so any heavy tasks of screen will not affect the smoothness of the animation.
                                post(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (isVisibleToUser())
                                            postOnContentViewCreated();
                                    }
                                }, 250);
                            }
                            mHasAnimationFinished = true;
                        }
//						@Override
//						public void onAnimationCancel(Animator animation) {
//							if (mHasActivityCreated) {
//								Log.i("Screen", "onAnimatorEnds: calling onContentViewCreated");
//								postOnContentViewCreated();
//							}
//							mHasAnimationFinished = true;
//						}
                    });

                } else {
                    if (mHasActivityCreated) {
                        postOnContentViewCreated();
                    }
                    mHasAnimationFinished = true;
                }
                return at;
            } else {
                if (mHasActivityCreated) {
                    postOnContentViewCreated();
                }
                mHasAnimationFinished = true;
            }
        }
        return super.onCreateAnimation(transit, enter, nextAnim);
    }

    private boolean mHasAnimationFinished = false;


    protected boolean isDialog() {
        return false;
    }

    //	private int mLoadedSounds = 0;
    private void postOnContentViewCreated() {
        Log.i("Screen", "postOnContentViewCreated: " + getScreenId());
        final Activity act = getActivity();
        if (act != null && !act.isFinishing() && !isDetached()) {


            onContentViewCreated(mTempSavedInstanceStates);
        }
        mHasActivityCreated = false;
        mHasAnimationFinished = false;
        mTempSavedInstanceStates = null;
        mIsPaused = false;
    }

   


    protected abstract void onContentViewCreated(Bundle savedInstanceStates);


    LayoutInflater mInflater;

    protected LayoutInflater getInflater() {
        return mInflater;
    }
//	protected void onSoundResourcesLoaded() {
//		
//	}

    public final void loadScreen(Screen scr) {
        canTouch = false;
        MainActivity act = getMainActivity();
        if (act != null) {
            act.loadScreen(scr);
        }
    }

    public final void loadScreenNoTransition(Screen scr) {
        canTouch = false;
        MainActivity act = getMainActivity();
        if (act != null) {
            act.loadScreenNoTransition(scr);
        }
    }

    public final void loadScreen(Screen scr, int enterAnim, int exitAnim, int popEnterAnim, int popExitAnim) {
        canTouch = false;
        MainActivity act = getMainActivity();
        if (act != null) {
            act.loadScreen(scr, enterAnim, exitAnim, popEnterAnim, popExitAnim, false, true, true, false);
        }
    }

    public MainActivity getMainActivity() {
        try {
            return (MainActivity) getActivity();

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    final Handler mHandler = new Handler();

    protected void runOnUiThread(Runnable r) {
        if (isVisibleToUser())
            mHandler.post(r);
    }

    /**
     * Posts or posts delayed the specified task.
     *
     * @param r     Task to be posted.
     * @param delay 0 or negative value means no delay.
     */
    protected void post(Runnable r, long delay) {
        if (isVisibleToUser()) {
            if (delay > 0)
                mHandler.postDelayed(r, delay);
            else
                mHandler.post(r);
        }
    }

    public Handler getHandler() {
        return mHandler;
    }

    protected View findViewById(int id) {
        View v = getView();
        if (v != null) {
            return v.findViewById(id);
        }
        return null;
    }


    protected ContentResolver getContentResolver() {
        return getMainActivity().getContentResolver();
    }

    

    private boolean mIsPaused = false;


    @Override
    public void onPause() {
        canTouch = false;
        super.onPause();
        mIsPaused = true;
    }


    @Override
    public void onStart() {
        canTouch = false;
        super.onStart();
    }

    @Override
    public void onResume() {
        super.onResume();
        mIsPaused = false;

        // Một số device yếu khi đang load screen mà click liên tục vào nút back trên headerbar sẽ bị lỗi.
        // Tạo delay 1s không cho touch liên tục. Các screen kế thừa sẽ sử dụng canTouch để xử lý vấn đề click.
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                canTouch = true;
            }
        }, 1000);
    }

    @Override
    public final void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        onSaveScreenStates(outState);
    }

   

    public boolean isOnUiThread(Thread thread) {
        return Looper.getMainLooper().getThread() == thread;
    }


    protected void onSaveScreenStates(Bundle states) {

    }

   

    public boolean isVisibleToUser() {
//		boolean visible = !mIsPaused;
//		MainActivity act = (MainActivity)getActivity();
//		if (act != null) {
//			return visible && !act.isPaused();
//		}
//		return false;
        return getActivity() != null;
    }


   

    public boolean getCanTouch() {
        return canTouch;
    }


    public interface ScreenResultListener {
        void onScreenResult(Screen sender, int requestCode, Object data);
    }

    ScreenResultListener mScreenResultListener;

    public class ScreenResult {
        private int requestCode = Integer.MIN_VALUE;

        private ScreenResult(int requestCode) {
            this.requestCode = requestCode;
        }

        public void setData(Object data) {
            if (mScreenResultListener != null) {
                mScreenResultListener.onScreenResult(Screen.this, requestCode, data);
            }
            mScreenResultListener = null;
        }

        public int getRequestCode() {
            return requestCode;
        }
    }

    private ScreenResult mRegisteredResult;

    protected ScreenResult getRegisteredScreenResult() {
        return mRegisteredResult;
    }

    public void registerScreenResult(int requestCode, ScreenResultListener l) {
        mRegisteredResult = new ScreenResult(requestCode);
        mScreenResultListener = l;
    }

   

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
       

    }


//	@Override
//	public boolean onKeyUp(int keyCode, KeyEvent event) {
//		if (keyCode == KeyEvent.KEYCODE_MENU) {
//			if (mHeaderBar != null && mHeaderBar.isMenuButtonAvailable()) {
//				mHeaderBar.toggleMenu();
//				return true;
//			}
//		}
//		return super.onKeyUp(keyCode, event);
//	}
}
